#ifndef CCAMERA_H
#define CCAMERA_H

#include <QObject>
#include <QStringList>
#include <QList>
#include <QCameraDevice> // 包含 QCameraDevice 定义

#include "readthread.h" // 包含 ReadThread 定义

// 前置声明
struct AVFrame;
// class ReadThread; // ReadThread.h 已包含
class VideoDecode;

class CCamera : public QObject
{
    Q_OBJECT
public:
    explicit CCamera(QObject *parent = nullptr);
    ~CCamera() override;

    // --- 公共接口 ---

    /**
     * @brief 获取当前可用的摄像头设备描述列表
     * @return 字符串列表，用于 UI 显示
     */
    QStringList getAvailableCamerasDescriptions() const;

    /**
     * @brief 根据 UI 列表中的索引选择要使用的摄像头
     * @param index 摄像头在列表中的索引
     * @return 是否选择成功
     */
    bool selectCamera(int index);

    /**
     * @brief 获取当前选中的摄像头的描述名称
     * @return 设备描述字符串，如果未选择则为空
     */
    QString getSelectedCameraDescription() const;

    /**
     * @brief 获取选中的摄像头用于 FFmpeg 打开的名称 (例如 "video=设备描述")
     * @return FFmpeg 可用的设备名称字符串
     */
    QString getSelectedCameraNameForFFmpeg() const;

    /**
     * @brief 开始捕获选定摄像头的视频帧
     * @return 是否成功启动（或已启动）
     */
    bool startCapture();

    /**
     * @brief 停止捕获视频帧
     */
    void stopCapture();

    /**
     * @brief 检查摄像头是否正在捕获中
     * @return 如果正在捕获则返回 true
     */
    bool isCapturing() const;

signals:
    /**
     * @brief 当发现的摄像头列表更新时发出此信号
     * @param descriptions 新的摄像头描述列表
     */
    void cameraListUpdated(const QStringList& descriptions);

    /**
     * @brief 当有新的视频帧准备好时发出此信号
     * @param frame 指向 AVFrame 的指针。注意：这是一个克隆出来的帧，接收者使用完毕后【必须】调用 av_frame_free(&frame) 来释放！
     */
    void frameReady(AVFrame* frame);

    /**
     * @brief 当摄像头捕获状态改变时发出此信号 (可选)
     * @param isCapturing 新的捕获状态
     */
    void captureStateChanged(bool isCapturing);

    /**
     * @brief 当摄像头操作发生错误时发出此信号
     * @param errorString 错误描述
     */
    void errorOccurred(const QString& errorString);

private slots:
    /**
     * @brief 内部槽函数，处理来自 ReadThread 的原始帧信号
     * @param frame ReadThread 发出的帧指针 (克隆帧)
     */
    void onFrameReceived(AVFrame* frame);

    /**
     * @brief 内部槽函数，处理来自 ReadThread 的状态改变信号
     * @param state ReadThread 的播放状态
     */
    void onThreadStateChanged(ReadThread::PlayState state);

private:
    /**
     * @brief 发现系统中的摄像头设备并更新列表
     */
    void discoverCameras();

    QList<QCameraDevice> availableCameras_;       // 存储检测到的摄像头设备对象
    QStringList cameraDescriptions_;            // 存储用于 UI 显示的摄像头描述
    QCameraDevice selectedCamera_;              // 当前选中的摄像头设备对象
    ReadThread* readThread_ = nullptr;          // 读取线程实例
    bool isCapturing_ = false;                  // 当前是否正在捕获
};

#endif // CCAMERA_H
